package com.uziot.bucket.common.concurrent;

/**
 * @author shidt
 * @version V1.0
 * @className ThreadLocalDemo
 * @date 2020-09-13 01:12:36
 * @description <br/>
 * 1、 ThreadLocal是线程变量，属于某个线程私有的信息存储容器，局部区域。
 * 2、有3个常用方法get/set/initialValue
 * 3、建议使用private static
 * 4、构造器调用属于构造执行线程，因此在构造器中使用Thread会执行调用线程值变化。
 * 5、线程发起调用，InheritableThreadLocal线程对象，发起创建新线程会将ThreadLocal中的值传递给子线程。
 */

public class ThreadLocalDemo {
    /**
     * 1、可直接初始化
     */
    private static final ThreadLocal<Integer> THREAD_LOCAL = new ThreadLocal<>();

    /**
     * 2、可初始化变量值，覆盖匿名内部类对象返回值即可
     */
    private static final ThreadLocal<Integer> THREAD_LOCAL2 = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 1999;
        }
    };
    /**
     * 3、lambda表达式方式初始化值
     */
    private static final ThreadLocal<Integer> THREAD_LOCAL3 = ThreadLocal.withInitial(() -> 1);

    /**
     * 4、线程发起调用，发起创建新线程会将ThreadLocal中的值传递给子线程。
     */
    private static final ThreadLocal<Integer> THREAD_LOCAL4 = InheritableThreadLocal.withInitial(() -> 1);





    public static void main(String[] args) {
        String name = Thread.currentThread().getName();
        System.out.println("当前线程：" + name + ",ThreadLocal值:" + THREAD_LOCAL3.get());

        for (int i = 0; i < 5; i++) {
            new Thread(new MyRunnable()).start();
        }

        System.out.println("当前线程：" + name + ",ThreadLocal值:" + THREAD_LOCAL3.get());

    }


    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            // 获取当前的值
            Integer integer = THREAD_LOCAL3.get();
            System.out.println("当前线程: " + name + "，值：" + integer);
            // 减少1
            THREAD_LOCAL3.set(integer - 1);
            System.out.println("减量后线程：" + name + "值：" + THREAD_LOCAL3.get());
        }
    }


}
